﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model4D
{
    /// <summary>
    /// Класс описывающий матрицу и элементарные операции над ней.
    /// </summary>
    class Matrix
    {
        #region === membres ===

        double[,] _m = null;

        #endregion

        public Matrix(int N)
        {
            _m = new double[N, N];

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    _m[i, j] = 0;
                }
            }
        }

        public int Size => _m != null ? _m.GetUpperBound(0) + 1 : 0;

        public double this[int x, int y]
        {
            get { return _m[x, y]; }
            set { _m[x, y] = value; }
        }

        /// <summary>
        /// Оператор умножения Матрицы на вектор.
        /// </summary>
        /// <param name="matrix">Матрица.</param>
        /// <param name="vector">Вектор.</param>
        /// <returns>Вектор результат.</returns>
        static public Vector operator *(Matrix matrix, Vector vector)
        {
            if (matrix.Size != vector.Size)
                throw new Exception("Невозможно вычислить произведение. Размер матрицы не равен размеру вектора.");

            Vector v = new Vector(vector.Size);

            for (int i = 0; i < vector.Size; i++)
            {
                double x = 0;

                for (int j = 0; j < matrix.Size; j++)
                {
                    x += matrix[i, j] * vector[j];
                }

                v.X[i] = x;
            }

            return v;
        }

        /// <summary>
        /// Оператор умножения матриц.
        /// </summary>
        /// <param name="m1">Матрица 1.</param>
        /// <param name="m2">Матрица 2.</param>
        /// <returns>Матрица результат.</returns>
        static public Matrix operator *(Matrix m1, Matrix m2)
        {
            if (m1.Size != m2.Size)
                throw new Exception("Невозможно вычислить произведение. Число строк в первой матрице не равно число столбцов во второй.");

            int size = m1.Size;
            Matrix result = new Matrix(size);

            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    double cij = 0;

                    for (int k = 0; k < size; k++)
                    {
                        cij += m1[i, k] * m2[k, j];
                    }

                    result[i, j] = cij;
                }
            }

            return result;
        }
    }
}
